package me.stone.stanimeclient.page.fan

import android.annotation.SuppressLint
import android.content.Intent
import android.content.pm.ActivityInfo
import android.os.Bundle
import android.view.View
import androidx.activity.viewModels
import androidx.core.graphics.Insets
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
import androidx.drawerlayout.widget.DrawerLayout.DrawerListener
import androidx.lifecycle.lifecycleScope
import androidx.media3.common.util.UnstableApi
import com.didi.drouter.annotation.Router
import com.google.android.material.bottomsheet.BottomSheetDialog
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.distinctUntilChangedBy
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.launch
import me.stone.stanimeclient.Constants
import me.stone.stanimeclient.R
import me.stone.stanimeclient.base.AbsViewBindingActivity
import me.stone.stanimeclient.core.common.extensions.detachParent
import me.stone.stanimeclient.core.common.extensions.toggleSystemBars
import me.stone.stanimeclient.core.ui.adapters.FanEpisodeAdapter
import me.stone.stanimeclient.core.ui.databinding.AgeExoPlayerBottomMenuBinding
import me.stone.stanimeclient.core.ui.item.AgeBottomMenuHelper
import me.stone.stanimeclient.core.ui.player.AgeExoPlayerHelper
import me.stone.stanimeclient.core.ui.player.AgeExoPlayerUIBinding
import me.stone.stanimeclient.databinding.ActivityFanInfoBinding
import timber.log.Timber
import javax.inject.Inject

@UnstableApi
@AndroidEntryPoint
@Router(path = Constants.DROUTE_PATH_FAN_INFO)
class FanInfoActivity : AbsViewBindingActivity<ActivityFanInfoBinding>() {

    private val viewModel: FanInfoViewModel by viewModels()

    private val detailId get() = intent.getIntExtra(
        Constants.DROUTE_EXTRA_KEY_ID, 0
    )


    override fun buildViewBinding(): ActivityFanInfoBinding {
        return ActivityFanInfoBinding.inflate(layoutInflater).apply {
            this.viewModel = this@FanInfoActivity.viewModel
            this.lifecycleOwner = this@FanInfoActivity
            executePendingBindings()
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding.toolbar.setNavigationOnClickListener { finish() }
        // 动态修改当前查看的番剧ID
        observeDetailId()
        // 观察当前需要播放的番剧
        observeEpisodeSelect()
        // 动态修改UI内容
        observeUIChanged()
        // 加载当前番剧数据
        viewModel.loadData(detailId)
    }

    private fun observeDetailId() = lifecycleScope.launch {
        viewModel.detailId.collectLatest {
            if (it == 0 || detailId == it) return@collectLatest
            // 当前番剧和传入的番剧Id不一致，表示从该页查看过其他番剧
            // 暂不做查看缓存，没想好如果查看过多的番剧，如果药一个个回退，如果直接关闭页面的操作
            // 直接替换当前查看的番剧内容，这里直接替换加载的Id
            intent = Intent().apply { putExtra(Constants.DROUTE_EXTRA_KEY_ID, it) }
            Timber.d("fan item id changed: $it")
        }
    }

    private fun observeUIChanged() = lifecycleScope.launch {
        launch {
            viewModel.showPlayer.distinctUntilChangedBy { it }.collectLatest {
                Timber.d("show player: $it")
            }
        }

        launch {
            viewModel.canShowEpisodeUI.distinctUntilChangedBy { it }.collectLatest {
                viewModel.visibleEpisode(binding.stubEpisode, it, this@FanInfoActivity)
            }
        }

        launch {
            viewModel.canShowSeriesUI.distinctUntilChangedBy { it }.collectLatest {
                viewModel.visibleSeries(binding.stubSeries, it, this@FanInfoActivity)
            }
        }

        launch {
            viewModel.canShowRecommendUI.distinctUntilChangedBy { it }.collectLatest {
                viewModel.visibleRecommend(binding.stubRecommend, it, this@FanInfoActivity)
            }
        }
    }

    private fun observeEpisodeSelect() = lifecycleScope.launch {
        viewModel.selectedEpisodeItem
            .filterNotNull()
            .distinctUntilChangedBy { it }
            .collectLatest {
                lazyInitPlayer
                playerHelper.playWithEpisodeItem(it)
            }
    }

    private val playerHelper by lazy {
       AgeExoPlayerHelper.bind(binding.playerPanel, this)
    }

    private val lazyInitPlayer: Unit by lazy {
        playerHelper.initializePlayer()
        observeHelperFlows()
    }

    private val playerUIBinding: AgeExoPlayerUIBinding
        get() = playerHelper.uiBinding

    private var isFullscreen: Boolean = false

    @Inject
    lateinit var bottomMenuHelper: AgeBottomMenuHelper

    private val bottomMenuUIBinding by lazy {
        AgeExoPlayerBottomMenuBinding.inflate(layoutInflater).apply {
            bottomMenus = bottomMenuHelper
            lifecycleOwner = this@FanInfoActivity
            executePendingBindings()
        }
    }

    private val bottomMenuSheetDialog by lazy {
        BottomSheetDialog(this, R.style.BottomSheetDialog).apply {
            setContentView(bottomMenuUIBinding.root)
        }
    }

    private fun observeHelperFlows() {
        lifecycleScope.launch {
            playerUIBinding.fullscreenFlow.collect {
                toggleFullscreen(it)
            }
        }

        lifecycleScope.launch {
            playerUIBinding.actionFlow.collect {
                when (it) {
                    AgeExoPlayerUIBinding.Action.Menu -> {
                        if (!isFullscreen) popMenuBottomSheetDialog()
                    }
                    AgeExoPlayerUIBinding.Action.Episode -> {
                        if (isFullscreen) showRightMenus()
                    }
                    else -> {}
                }
            }
        }

        lifecycleScope.launch {
            playerHelper.closeDrawer.collect {
                hideRightMenus()
            }
        }

        lifecycleScope.launch {
            playerUIBinding.fullscreenFlow.collect {
                isFullscreen = it
            }
        }
    }

    private fun toggleFullscreen(fullscreen: Boolean) {
        val fanDataUI: Int; val fullscreenContainer: Int
        if (fullscreen) {
            fanDataUI = View.GONE; fullscreenContainer = View.VISIBLE
        } else {
            fanDataUI = View.VISIBLE; fullscreenContainer = View.GONE
        }
        binding.containerFullscreen.visibility = fullscreenContainer
        binding.fanDataContainer.visibility = fanDataUI
        binding.containerPlayer.visibility = fanDataUI

        val controller = WindowCompat.getInsetsController(window, window.decorView)
        val systemBarInsetFlag = WindowInsetsCompat.Type.systemBars()
        if (fullscreen) {
            controller.hide(systemBarInsetFlag)
            controller.systemBarsBehavior =
                WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
            requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
        } else {
            controller.show(systemBarInsetFlag)
            controller.systemBarsBehavior =
                WindowInsetsControllerCompat.BEHAVIOR_DEFAULT
            @SuppressLint("SourceLockedOrientationActivity")
            requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
        }

        binding.root.postOnAnimation {
            val panelView = binding.playerPanel.root
            panelView.detachParent()
            if (fullscreen) {
                toggleSystemBars(true)
                binding.containerFullscreen.addView(panelView, 0)
            } else {
                binding.containerPlayer.addView(panelView, 0)
            }
        }
    }

    private fun showRightMenus() {
        binding.drawerListEpisode.adapter = viewModel.episodeBindingHelper.adapter
        FanEpisodeAdapter.attachGridManger(binding.drawerListEpisode, 2)
        binding.containerFullscreen.openDrawer(binding.drawerListEpisode)
        playerUIBinding.playerView.hideController()
        binding.drawerListEpisode.post {
            viewModel.episodeBindingHelper.adapter.mSelectItemPos?.let {
                if (it >= 0)  binding.drawerListEpisode.scrollToPosition(it)
            }
        }

        binding.containerFullscreen.addDrawerListener(object : DrawerListener {
            override fun onDrawerSlide(drawerView: View, slideOffset: Float) {}

            override fun onDrawerOpened(drawerView: View) {
                playerHelper.showDrawerMenu()
            }

            override fun onDrawerClosed(drawerView: View) {
                playerHelper.closeDrawMenu()
            }

            override fun onDrawerStateChanged(newState: Int) {}
        })
    }

    private fun hideRightMenus() {
        binding.containerFullscreen.closeDrawers()
    }

    private fun popMenuBottomSheetDialog() {
        bottomMenuSheetDialog.show()
    }

    override fun getCustomInsets(insets: Insets): Insets? {
        // 修正部分手机全屏后不会自动识别顶部状态栏衬边高度的问题
        return if (isFullscreen) null else insets
    }

}
